<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

	interface INode
	{
		public function getLongitude();
		public function getLatitude();	
	}
    
    interface IGenerator
    {
        public function generate();
    }
	
	abstract class AbstractNode implements INode
	{
		protected $longitude = 0;
		public function getLongitude() { return $this->longitude; }
		public function setLongitude($longitude) { $this->longitude = $longitude; }

		protected $latitude = 0;
		public function getLatitude() { return $this->latitude; }
		public function setLatitude($latitude) { $this->latitude = $latitude; }
		
		public static function getDistance(INode $node1, INode $node2)
		{
			$x1 = $node1->getLongitude();
			$y1 = $node1->getLatitude();
			$x2 = $node2->getLongitude();
			$y2 = $node2->getLatitude();

			/*$x = abs($x2 - $x1);
			$y = abs($y2 - $y1);
			$d = sqrt(pow($x, 2) + pow($y, 2));*/
			/*echo "XX<br /><pre>";
			print_r($node1);
			print_r($node2);
			echo " </pre>===> ".$x2." - ".$x1.", ".$y2." - ".$y1. " = ".$d."<br />";*/
            //$d = 5;
            //return $d;
            return AbstractNode::haversine($node1, $node2);
		}

        public static function haversine(INode $node1, INode $node2)
        {
            if(!is_numeric($node1->getLatitude()) || !is_numeric($node1->getLongitude()) || !is_numeric($node2->getLatitude()) || !is_numeric($node2->getLongitude()))
                return PHP_INT_MAX;

            $start = array($node1->getLatitude(), $node1->getLongitude());
            $finish = array($node2->getLatitude(), $node2->getLongitude());
            //echo is_numeric($node1->getLatitude()).", ".is_numeric($node1->getLongitude())." : ".is_numeric($node2->getLatitude()).", ".is_numeric($node2->getLongitude())."<br />";

            $theta = $start[1] - $finish[1];
            $distance = (sin(deg2rad($start[0])) * sin(deg2rad($finish[0]))) + (cos(deg2rad($start[0])) * cos(deg2rad($finish[0])) * cos(deg2rad($theta)));
            $distance = acos($distance);
            $distance = rad2deg($distance);
            $distance = $distance * 60 * 1.1515;
            $miles = round($distance, 2);
            $km = $miles * 1.609344;
            return $km;
        }
	}
	
?>